<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <style>
      /* 填写样式 */
    </style>
  </head>

  <body>
    <!-- 填写标签 -->
    <script type="text/javascript">
        /**
         * 模板题，这里提供三种解法，
         * apply、call、bind中前两者比较相似， 
         * eg.`f.apply(oTarget, arguments);`和`return f.call(oTarget, ...arguments);`返回的是立即执行函数
         * `f.bind(oTarget);`返回的是一个非立即执行函数，需要手动调用
         * 
         * 对于参数的传递三种方法皆有所不同
         * apply需使用arguments接受参数（必须是这个词，不能自定义修改）
         * call需使用...arguments接受参数（同上）
         * bind无需显式声明接受参数，直接传即可，
         * 所有参数会按顺序被接收
         */

      // 填写JavaScript
      function bindThis(f, oTarget) {
        return function () {
          return f.apply(oTarget, arguments);
        };
      }

      function bindThis1(f, oTarget) {
        return function () {
          return f.call(oTarget, ...arguments);
        };
      }

      const bindThis2 = (f, oTarget) => f.bind(oTarget);

      let student = {
        name: "wow",
      };

      //用于绑定的方法
      function getMyName(arg1, arg2) {
        console.log(`我是${this.name},${arg1},${arg2}~`);
      }

      //绑定
      let getMyNameBind = bindThis(getMyName, student);
      let getMyNameBind1 = bindThis1(getMyName, student);
      let getMyNameBind2 = bindThis2(getMyName, student);

      //调用
      getMyNameBind("你好呀", "你真帅🟢");
      getMyNameBind1("你好呀", "你真帅🟠");
      getMyNameBind2("你好呀", "你真帅🔴");
    </script>
  </body>
</html>
